﻿using System;
using System.Threading;

namespace IronCow
{
    public static class RtmAsyncHelper
    {
        public static void Execute(Action action, Action callback)
        {
            if (action == null)
                throw new ArgumentNullException("action");
            ThreadPool.QueueUserWorkItem(ExecuteActionCallback0, new ExecuteState0(action, callback));
        }

        public static void Execute<T>(Func<T> action, Action<T> callback)
        {
            if (action == null)
                throw new ArgumentNullException("action");
            ThreadPool.QueueUserWorkItem(ExecuteActionCallback1<T>, new ExecuteState1<T>(action, callback));
        }

        private class ExecuteState0
        {
            public Action Action { get; private set; }
            public Action Callback { get; private set; }

            public ExecuteState0(Action action, Action callback)
            {
                Action = action;
                Callback = callback;
            }
        }

        private class ExecuteState1<T>
        {
            public Func<T> Action { get; private set; }
            public Action<T> Callback { get; private set; }

            public ExecuteState1(Func<T> action, Action<T> callback)
            {
                Action = action;
                Callback = callback;
            }
        }

        private static void ExecuteActionCallback0(object state)
        {
            var executeState = (ExecuteState0)state;
            executeState.Action();
            if (executeState.Callback != null)
            {
                executeState.Callback();
            }
        }

        private static void ExecuteActionCallback1<T>(object state)
        {
            var executeState = (ExecuteState1<T>)state;
            T result = executeState.Action();
            if (executeState.Callback != null)
            {
                executeState.Callback(result);
            }
        }
    }
}
